using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.SharedSource.SqlServer.MDDE.Middleware;
using System.Xml;

namespace Microsoft.SharedSource.SqlServer.MDDE.ManagementStudio
{
    internal partial class UpgradeTemplateShowDifferences : UpgradeTemplateBase
    {
        XmlDocument differencesReport;
        XmlDocument changesXml;
        XmlDocument templateConfigurations;

        public UpgradeTemplateShowDifferences(UpgradeTemplateWizardController controller)
            : base(controller)
        {
            InitializeComponent();
        }

        private void workerDeletedComponents_DoWork(object sender, DoWorkEventArgs e)
        {
            // Get the template body from wizard configurations.
            XmlNode xBody = controller.WizardConfigurations.SelectSingleNode(
                "//Form[@Name=\"GetTemplateLocation\"]/UserInput[@Name=\"TemplateBody\"]");

            string templateBody = xBody.Attributes["Value"].Value;

            // Get the differences report from backend.
            OperationResult result = MDDEManager.GetTemplateDifferences(
                controller.RepositoryConnectionString, controller.TemplateName, templateBody);

            if (result.SuccessStatus == true)
            {
                differencesReport = (XmlDocument)result.OperationOutputParameters[0];
                changesXml = (XmlDocument)result.OperationOutputParameters[1];
                templateConfigurations = (XmlDocument)result.OperationOutputParameters[2];
            }
        }

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (tabControl1.SelectedIndex == 2)
            {
            }
        }

        private void workerDeletedComponents_RunWorkerCompleted(
            object sender, RunWorkerCompletedEventArgs e)
        {
            tpgDeleted.Text = "Deleted Components";
            tpgAdded.Text = "Added Components";
            tpgChanges.Text = "Updated Components";

            if (differencesReport == null || changesXml == null)
            {
                MessageBox.Show(
                       "Some errors occured while generating differences between the templates.",
                       "Operation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // Populate the Deleted components list.
            foreach (XmlNode xComponent in
                differencesReport.SelectNodes("//DeletedComponent/Component"))
                dgDeleted.Rows.Add(xComponent.Attributes["Name"].Value,
                    xComponent.Attributes["Uri"].Value);

            // Populate the Added components list.
            foreach (XmlNode xComponent in
                differencesReport.SelectNodes("//AddedComponent/Component"))
                dgAdded.Rows.Add(xComponent.Attributes["Name"].Value,
                    xComponent.Attributes["Uri"].Value);

            // Populate the changes xml tree.
            trvChanges.Nodes.Add(CreateTreeNodeFromXmlNode(changesXml.DocumentElement));

            // Enable controls.
            EnableControls();
        }

        private TreeNode CreateTreeNodeFromXmlNode(XmlNode xNode)
        {
            TreeNode tNode = new TreeNode();

            // Tag the tree node.
            tNode.Tag = xNode;

            // Provide the name to tree node.
            try
            {
                // See if there is an attribute 'Name'
                tNode.Name = tNode.Text = xNode.Attributes["Name"].Value;
            }
            catch
            {
                tNode.Name = tNode.Text = xNode.Name;
            }

            // Add in the child nodes.
            foreach (XmlNode xChild in xNode.ChildNodes)
                tNode.Nodes.Add(CreateTreeNodeFromXmlNode(xChild));

            return tNode;
        }

        Dictionary<Control, bool> controlState = new Dictionary<Control, bool>();

        private void DisableControls()
        {
            controlState.Clear();

            foreach (Control ctrl in this.Controls)
            {
                controlState.Add(ctrl, ctrl.Enabled);
                ctrl.Enabled = false;
            }

            this.Cursor = Cursors.WaitCursor;
        }

        private void EnableControls()
        {
            foreach (KeyValuePair<Control, bool> kvp in controlState)
                kvp.Key.Enabled = kvp.Value;

            this.Cursor = Cursors.Default;
        }

        private void trvChanges_AfterSelect(object sender, TreeViewEventArgs e)
        {
            // Clear off the grid.
            dgProperties.Rows.Clear();

            // Populate the grid.
            if (trvChanges.SelectedNode.Tag != null && trvChanges.SelectedNode.Tag is XmlNode)
            {
                XmlNode propertyHost = (XmlNode)trvChanges.SelectedNode.Tag;

                foreach (XmlAttribute xAttr in propertyHost.Attributes)
                    dgProperties.Rows.Add(xAttr.Name, xAttr.Value);
            }
        }

        protected override void btnNext_Click(object sender, EventArgs e)
        {
            // Locate any earlier entry for this form.
            XmlNode formShowDifferences =
                controller.WizardConfigurations.SelectSingleNode("//Form[@Name=\"ShowDifferences\"]");

            // Delete the earlier node if found.
            if (formShowDifferences != null)
                formShowDifferences.ParentNode.RemoveChild(formShowDifferences);

            // Create the form configuration node in the wizard configuration.
            XmlNode formNode =
                UIHelper.AppendChildElement(controller.WizardConfigurations.FirstChild, "Form",
                new string[] { "Name", "ShowDifferences" });

            // Add the new template configurations to wizard configurations.
            UIHelper.AppendChildElement(formNode, "UserInput", 
                new string[] { "Name","TemplateConfigurations",
                "Value", templateConfigurations.InnerXml});

            base.btnNext_Click(sender, e);
        }

        private void UpgradeTemplateShowDifferences_VisibleChanged(object sender, EventArgs e)
        {
            // Do nothing if the visibility is false.
            if (this.Visible == false)
                return;

            // Check if we have the form configuration in the wizard configuration.
            XmlNode xFormConfiguration =
                controller.WizardConfigurations.SelectSingleNode("//Form[@Name=\"ShowDifferences\"]");

            if (xFormConfiguration == null)
            {
                // Disable all the controls.
                DisableControls();

                // Initialize the deleted tab page.
                tpgDeleted.Text = "Deleted Components (Loading...)";
                tpgAdded.Text = "Added Components (Loading...)";
                tpgChanges.Text = "Updated Components (Loading...)";

                // Start off the worker thread.
                workerDeletedComponents.RunWorkerAsync();
            }
        }

        protected override void btnBack_Click(object sender, EventArgs e)
        {
            // Clear off all the controls.
            dgAdded.Rows.Clear();
            dgDeleted.Rows.Clear();
            dgProperties.Rows.Clear();
            trvChanges.Nodes.Clear();

            // Nullify the component information.
            differencesReport = null;
            changesXml = null;
            templateConfigurations = null;

            // Locate any earlier entry for this form.
            XmlNode formShowDifferences =
                controller.WizardConfigurations.SelectSingleNode("//Form[@Name=\"ShowDifferences\"]");

            // Delete the earlier node if found.
            if (formShowDifferences != null)
                formShowDifferences.ParentNode.RemoveChild(formShowDifferences);

            base.btnBack_Click(sender, e);
        }
    }
}

